﻿using dreamwork.auth.api.Model.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace dreamwork.auth.api.Infrastructure
{
	public class ApplicationUserSqlServerRepository : IApplicationUserRepository
	{
		private readonly SqlServerDBContext _context;
		private readonly ILogger<ApplicationUserSqlServerRepository> _logger;
		public ApplicationUserSqlServerRepository(SqlServerDBContext context, ILogger<ApplicationUserSqlServerRepository> logger)
		{
			_context = context;
			_logger = logger;
		}

		public async Task AddAsync(ApplicationUser item)
		{
			try
			{
				var model = _context.ApplicationUsers.Add(item);
				await _context.SaveChangesAsync();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
			}
		}

		public async Task<ApplicationUser> GetAsync(Guid id)
		{
			try
			{
				return await _context.ApplicationUsers.FirstOrDefaultAsync(x => x.Id == id.ToString());
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return null;
			}
		}
		public async Task<ApplicationUser> GetAsync(Expression<Func<ApplicationUser, bool>> selector)
		{
			try
			{
				return await _context.ApplicationUsers.FirstOrDefaultAsync(selector);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return null;
			}
		}
		public async Task<IEnumerable<ApplicationUser>> GetListAsync(Expression<Func<ApplicationUser, bool>> selector)
		{
			try
			{
				return await _context.ApplicationUsers.Where(selector).ToListAsync();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return null;
			}
		}
		public async Task<IEnumerable<ApplicationUser>> GetAllAsync()
		{
			try
			{
				return await _context.ApplicationUsers.ToListAsync();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return new List<ApplicationUser>();
			}
		}

		public async Task<bool> RemoveAsync(Guid id)
		{
			try
			{
				var model = await _context.ApplicationUsers.FirstOrDefaultAsync(x => x.Id == id.ToString());
				var actionResult = _context.ApplicationUsers.Remove(model);
				//TODO what is the return value of remove.
				return true;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return false;
			}
		}

		public async Task<bool> UpdateAsync(ApplicationUser user)
		{
			try
			{
				_context.ApplicationUsers.Update(user);
				var actionResult = await _context.SaveChangesAsync();
				return actionResult > 0;

			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return false;
			}
		}
		public async Task<bool> RemoveAllAsync()
		{
			try
			{
				var models = await _context.ApplicationUsers.ToListAsync();
				_context.ApplicationUsers.RemoveRange(models);
				return true;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, ex.Message);
				return false;
			}
		}
	}
}
